﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using NetTaste;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Logging;
using System.Linq.Expressions;
using NPOI.SS.Formula.Functions;
using DFGK_WMS.Model.Enum;

namespace DFGK_WMS.Repository
{
    /// <summary>
    /// 出库管理
    /// </summary>
    public class TShippingOrderDetailRepository : BaseRepository<TShippingOrderDetail>, ITShippingOrderDetailRepository
    {
        private readonly ITShippingLockCellRepository lockCellRepository;

        public TShippingOrderDetailRepository(DFGK_DB context, IMapper mapper,ITShippingLockCellRepository lockCellRepository) : base(context, mapper)
        {
            this.lockCellRepository = lockCellRepository;
        }

        /// <summary>
        /// 添加出库管理 多个物料版本
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddTShippingOrderDetailPlus(TShippingOrderDetailPlusDTO model,out string msg)
        {
            Console.WriteLine(model.WhId);
            msg = "添加成功";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    var isHave=Context.TShippingOrderDetails.Any(s=>s.OrderSn==model.OrderSn);
                    if(isHave)
                    {
                        msg = "领用单号重复，领用单已存在";
                        return false;
                    }
                    foreach (var mater in model.shippingOrderDetailPlusLockCellDTOs)
                    {
                                            
                        var inv = Context.TInventories.Where(s => s.LocationCode.ToString() == mater.CellCode && s.Status == 1 && s.MaterialCode==mater.MaterialCode)
                            .FirstOrDefault();
                        if (inv == null)
                        {
                            msg = "找不到库存记录，或者库存正在出库";
                            return false;
                        }

                        if (inv.AvailableQty < mater.MaterialNum)
                        {
                            msg = mater.CellCode + "仓位，库存数量不足，数量还剩：" + inv.AvailableQty;
                            return false;
                        }
                        inv.Status = 4;
                        Context.TInventories.Update(inv);

                        TShippingOrderDetail shippingOrderDetail = new TShippingOrderDetail();
                        shippingOrderDetail.OrderSn = model.OrderSn; //同一个订单号
                        shippingOrderDetail.MaterialId=mater.MaterialId;
                        shippingOrderDetail.MaterialName = mater.MaterialName;
                        shippingOrderDetail.MaterialTypeCode = ""; //规格型号 这里把物料类型代替
                        shippingOrderDetail.WarehouseCode = "";
                        shippingOrderDetail.WarehouseName = model.WhName; //hn
                        shippingOrderDetail.WarehouseId=model.WhId; //hn
                        shippingOrderDetail.AreaCode = "";
                        shippingOrderDetail.AreaName = "";
                        shippingOrderDetail.BatchNo = "";
                        //shippingOrderDetail.UnitName = mater;
                        shippingOrderDetail.Qty = mater.MaterialNum;
                        shippingOrderDetail.Status = 0 ;
                        shippingOrderDetail.DeptName = model.NeedDeptName;
                        shippingOrderDetail.StationName = "";
                        shippingOrderDetail.CreateDate = DateTime.Now;
                        shippingOrderDetail.CreateUserName = model.NowUserRealName;
                        shippingOrderDetail.CreateUserId = model.NowUserId;

                        Context.TShippingOrderDetails.Add(shippingOrderDetail);
                        Context.SaveChanges();

                        //货位锁定明细
                        TShippingLockCell m = new TShippingLockCell();
                        m.OrderDetailId = shippingOrderDetail.Id;
                        m.InventoryId = inv.Id;
                        m.CellId = inv.LocationId;
                        m.CellCode = inv.LocationCode;
                        m.CellName = inv.LocationName;
                        m.PalletBarcode = inv.PalletBarcode;
                        m.WhId = inv.WarehouseId;
                        m.CellDepthIndex = 0;
                        m.StackingStorageId = inv.StackingStorageId;
                        m.OutQty = mater.MaterialNum;
                        m.InventoryQty = inv.AvailableQty;
                        m.MaterialId = inv.MaterialId;
                        m.MaterialName = inv.MaterialName;
                        m.MaterialCode = inv.MaterialCode;
                        m.MaterialKeyId = inv.MaterialKeyId;
                        m.BatchNo = inv.BatchNo;
                        m.CreateDate = DateTime.Now;
                        m.RoutewayId = inv.RoutewayId;
                        m.pickingItemId = mater.PickingItemId;//物资明细id  hn
                        m.IsPicking = false;
                        m.materialNorms = mater.MaterialNorms;//规格信号 hn
                        m.AreaCode=inv.AreaCode; //库区
                        m.AreaName = inv.AreaName;
                        Context.TShippingLockCells.Add(m);

                        Context.SaveChanges();
                    }
                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //事务回滚
                    tran.Rollback();
                    Context.TLogs.Add(new TLog()
                    {
                        LogType = 1,
                        ActionType = 6,
                        CreateDate = DateTime.Now,
                        Description = "添加出库单catch："+ex.Message,
                    });
                    Context.SaveChanges();
                    msg = "catch:"+ ex.Message;
                    return false;
                }
            }
        }

        public List<GetChukuDanDTO> GetAllTShippingOrderDetailPlus(int? billType, int? houseid, string? name, int pageIndex, int pageSize, out int totalCount,int? statusNum)
        {
            var listNoPage = Context.TShippingOrderDetails.AsEnumerable();
            if (billType != null)
                listNoPage = listNoPage.Where(s=>s.BillType==billType);
            if(houseid!=null)
                listNoPage=listNoPage.Where(s=>s.WarehouseId==houseid);
            if (name != null)
                listNoPage = listNoPage.Where(s => s.MaterialName == name);
            var items = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            var list= items.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            totalCount = items.Count();
            List<GetChukuDanDTO> resList = new List<GetChukuDanDTO>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCell>();
                var shippoutList = new List<TShippingOrderDetail>();
                foreach (var value in item)
                {
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        lockCellList.Add(item1);
                    }
                    shippoutList.Add(value);
                }
                resList.Add(new GetChukuDanDTO()
                {
                    Status = GetStatus(shippoutList,out int statusNumGet),
                    StatusNum = statusNumGet,
                    OrderSn = key,
                    CreateTime = shippoutList[0].CreateDate,
                    Sum = shippoutList.Sum(s=>s.Qty),
                    CreateUserName= shippoutList[0].CreateUserName,
                    AuditUserName= shippoutList[0].AuditUserName,
                    WarehouseName = shippoutList[0].WarehouseName ?? "",
                    DeptName = shippoutList[0].DeptName,
                    shippingOrders = lockCellList,
                });
            }
            if (statusNum != null)
                resList = resList.Where(s => s.StatusNum == statusNum).ToList();
            return resList;
        }
        private string GetStatus(List<TShippingOrderDetail> shippingGoods,out int statusNum)
        {
            int status = 4;
            statusNum = 4;
            string str = "未知状态";
            foreach (var item in shippingGoods)
            {
                if (item.Status != 4 && item.Status!=8)
                {
                    if (item.Status == 0)
                    {
                        status = 0;
                        statusNum = 0;
                        break;
                    }
                    else if (item.Status == 1)
                    {
                        status = 1;
                        statusNum = 1;
                        break;
                    }
                    else if (item.Status == 2)
                    {
                        status = 2;
                        statusNum = 2;
                        break;
                    }
                    else if (item.Status == 3)
                    {
                        status = 3;
                        statusNum = 3;
                        break;
                    }
                }
            }

            bool statusRes = true;
            foreach (var item in shippingGoods)
            {
                if (item.Status != 8)
                    statusRes = false;
            }
            if (statusRes)
            {
                str = "已回传";
                statusNum = 8;
                return str;
            }

            if (status == 0)
            {
                str = "创建";
                statusNum = 0;
                return str;
            } else if (status == 1)
            {
                str = "提交";
                statusNum = 1;
                return str;
            } else if (status == 2)
            {
                str = "审核通过";
                statusNum = 2;
                return str;
            }else if (status==3)
            {
                str = "作业中";
                statusNum = 3;
                return str;
            }else if (status == 4)
            {
                str = "已完成";
                statusNum = 4;
                return str;
            }
            return str;
        }
        /// <summary>
        /// 修改出库单为已回传
        /// </summary>
        /// <param name="orderSn"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool UpdOutShippingStatus(string orderSn,out string? errorMsg)
        {
            try
            {
                errorMsg = string.Empty;
                var outShipList = Context.TShippingOrderDetails.Where(s => s.OrderSn == orderSn);
                if (outShipList == null || outShipList.Count() <= 0)
                {
                    errorMsg = "找不到出库单";
                    Context.TLogs.Add(new TLog()
                    {
                        LogType = 1,
                        ActionType = 6,
                        CreateDate = DateTime.Now,
                        Description = "修改出库单为已回传时找不到出库单",
                    });
                    Context.SaveChanges();
                    return false;
                }
                foreach (var item in outShipList)
                {
                    item.Status = 8;
                }
                Context.UpdateRange(outShipList);
                if (Context.SaveChanges() <= 0)
                {
                    errorMsg = "找不到出库单";
                    Context.TLogs.Add(new TLog()
                    {
                        LogType = 1,
                        ActionType = 6,
                        CreateDate = DateTime.Now,
                        Description = "修改出库单为已回传时，SaveChanges失败",
                    });
                    Context.SaveChanges();
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                Context.TLogs.Add(new TLog()
                {
                    LogType = 1,
                    ActionType = 6,
                    CreateDate = DateTime.Now,
                    Description = "修改出库单为已回传时，catch:"+ex.Message,
                });
                Context.SaveChanges();
                throw;
            }
            
        }

        public GetChukuDanDTOHn? GetOneTShippingOrderDetailPlus(out bool res)
        {
            res = true;
            var listNoPage = Context.TShippingOrderDetails.AsEnumerable();
            var list = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            List<GetChukuDanDTO> resList = new List<GetChukuDanDTO>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCell>();
                var shippoutList = new List<TShippingOrderDetail>();
                foreach (var value in item)
                {
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        lockCellList.Add(item1);
                    }
                    shippoutList.Add(value);
                }
                resList.Add(new GetChukuDanDTO()
                {
                    Status = GetStatus(shippoutList, out int statusNumGet),
                    StatusNum = statusNumGet,
                    OrderSn = key,
                    CreateTime = shippoutList[0].CreateDate,
                    Sum = shippoutList.Sum(s => s.Qty),
                    CreateUserName = shippoutList[0].CreateUserName,
                    AuditUserName = shippoutList[0].AuditUserName,
                    WarehouseName = shippoutList[0].WarehouseName ?? "",
                    WarehouseId = shippoutList[0].WarehouseId.GetValueOrDefault(),
                    CreateUserId = shippoutList[0].CreateUserId.GetValueOrDefault(),
                    DeptName = shippoutList[0].DeptName,
                    shippingOrders = lockCellList,
                });
            }
            var resObj = resList.Where(s=>s.StatusNum==4).FirstOrDefault();
            if (resObj==null)
            {
                res = false;
                return null;
            }

            GetChukuDanDTOHn getChukuDanDTOHn = new GetChukuDanDTOHn();
            getChukuDanDTOHn.storeId = resObj.WarehouseId;
            getChukuDanDTOHn.pickingNumber = resObj.OrderSn;
            getChukuDanDTOHn.userId = 2064;

            List<TShippingLockCellDTOHn> shippingLockCellDTOHnList = new List<TShippingLockCellDTOHn>();
            foreach (var item in resObj.shippingOrders)
            {
                TShippingLockCellDTOHn shippingLockCellDTOHn = new TShippingLockCellDTOHn();
                shippingLockCellDTOHn.count = item.OutQty.GetValueOrDefault();
                shippingLockCellDTOHn.batch = item.BatchNo;
                shippingLockCellDTOHn.relationId = item.pickingItemId;
                shippingLockCellDTOHnList.Add(shippingLockCellDTOHn);
            }
            getChukuDanDTOHn.items = shippingLockCellDTOHnList;
            return getChukuDanDTOHn;
        }

        public bool AddTShippingOrderDetailNew(TShippingOrderDetailPlusDTO model, out string msg)
        {
            msg = "添加成功";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    var isHave = Context.TShippingOrderDetails.Any(s => s.OrderSn == model.OrderSn);
                    if (isHave)
                    {
                        msg = "领用单号重复，领用单已存在";
                        return false;
                    }
                    foreach (var mater in model.shippingOrderDetailPlusLockCellDTOs)
                    {

                        var invList = Context.TInventories.Where(s => s.LocationCode == mater.CellCode && s.Status == 1).ToList();
                        if (invList == null)
                        {
                            msg = "找不到库存记录，或者库存正在出库";
                            return false;
                        }
                        var numS = invList.Sum(s=>s.AvailableQty);
                        if (numS < mater.MaterialNum)
                        {
                            msg = mater.CellCode + "仓位，库存数量不足，数量还剩：" + numS;
                            return false;
                        }
                        foreach (var inv in invList)
                        {
                            inv.Status = 4;
                            Context.TInventories.Update(inv);
                        }
              

                        TShippingOrderDetail shippingOrderDetail = new TShippingOrderDetail();
                        shippingOrderDetail.OrderSn = model.OrderSn; //同一个订单号
                        shippingOrderDetail.MaterialId = mater.MaterialId;
                        shippingOrderDetail.MaterialName = mater.MaterialName;
                        shippingOrderDetail.MaterialTypeCode = ""; //规格型号 这里把物料类型代替
                        shippingOrderDetail.WarehouseCode = "";
                        shippingOrderDetail.WarehouseName = model.WhName; //hn
                        shippingOrderDetail.WarehouseId = model.WhId; //hn
                        shippingOrderDetail.AreaCode = invList[0].AreaCode;
                        shippingOrderDetail.AreaName = invList[0].AreaName;
                        shippingOrderDetail.BatchNo = invList[0].BatchNo;
                        //shippingOrderDetail.UnitName = mater;
                        shippingOrderDetail.Qty = mater.MaterialNum;
                        shippingOrderDetail.Status = 0;
                        shippingOrderDetail.DeptName = model.NeedDeptName;
                        shippingOrderDetail.StationName = "";
                        shippingOrderDetail.CreateDate = DateTime.Now;
                        shippingOrderDetail.CreateUserName = model.NowUserRealName;
                        shippingOrderDetail.CreateUserId = model.NowUserId;

                        Context.TShippingOrderDetails.Add(shippingOrderDetail);
                        Context.SaveChanges();

                        foreach (var inv in invList)
                        {
                            //货位锁定明细
                            TShippingLockCell m = new TShippingLockCell();
                            m.OrderDetailId = shippingOrderDetail.Id;
                            m.InventoryId = inv.Id;
                            m.CellId = inv.LocationId;
                            m.CellCode = inv.LocationCode;
                            m.CellName = inv.LocationName;
                            m.PalletBarcode = inv.PalletBarcode;
                            m.WhId = inv.WarehouseId;
                            m.CellDepthIndex = 0;
                            m.StackingStorageId = inv.StackingStorageId;
                            m.OutQty = mater.MaterialNum;
                            m.InventoryQty = inv.AvailableQty;
                            m.MaterialId = inv.MaterialId;
                            m.MaterialName = inv.MaterialName;
                            m.MaterialCode = inv.MaterialCode;
                            m.MaterialKeyId = inv.MaterialKeyId;
                            m.BatchNo = inv.BatchNo;
                            m.CreateDate = DateTime.Now;
                            m.RoutewayId = inv.RoutewayId;
                            m.pickingItemId = mater.PickingItemId;//物资明细id  hn
                            m.IsPicking = false;
                            m.materialNorms = mater.MaterialNorms;//规格信号 hn
                            m.AreaCode = inv.AreaCode; //库区
                            m.AreaName = inv.AreaName;
                            Context.TShippingLockCells.Add(m);
                        }

                        Context.SaveChanges();
                    }
                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //事务回滚
                    tran.Rollback();
                    Context.TLogs.Add(new TLog()
                    {
                        LogType = 1,
                        ActionType = 6,
                        CreateDate = DateTime.Now,
                        Description = "添加出库单catch：" + ex.Message,
                    });
                    Context.SaveChanges();
                    msg = "catch:" + ex.Message;
                    return false;
                }
            }
        }
    }
}